#include "include.h"

static const char *TAG = "MQTT_EXAMPLE";

static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;

    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
   
            /*
                    订阅    control
            */
            char topic_string[64];
            memset(topic_string,0,sizeof(topic_string));
            sprintf(topic_string,"%s/%s%s",TENCENT_MQTT_PRODUCT_ID,TENCENT_MQTT_DEVICE_NAME,"/control");

            msg_id = esp_mqtt_client_subscribe(client, topic_string, 0);
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d, topic=%s", msg_id,topic_string);

            char shadow_string[256];
            /*
                生成影子数据
            */
            build_shadow_string(shadow_string,sizeof(shadow_string));

            /*
                发送影子数据
            */
            char shadow_topic_string[64];
            sprintf(shadow_topic_string,"%s%s",TENCENT_SHADOW_TOPIC,TENCENT_MQTT_DEVICE_NAME);
            esp_mqtt_client_publish(client, shadow_topic_string, shadow_string, 0, 1, 0);
            
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;

        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);

            break;
        case MQTT_EVENT_UNSUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED:
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA:
            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            printf("DATA=%.*s\r\n", event->data_len, event->data);
            
            if(strstr(event->data,"{\"cmd\":\"take_photo\"}"))
            {
                /*>! 触发抓拍 */
                xEventGroupSetBits(app_event_handle, APP_EVENT_BIT_PHOTOGRAPH);
                /*>! 等待回调 */
                EventBits_t uxBits = xEventGroupWaitBits(app_event_handle,
                                                        APP_EVENT_BIT_PHOTOGRAPH_SUCCESS | APP_EVENT_BIT_PHOTOGRAPH_FAIL,
                                                        pdTRUE,
                                                        pdFALSE,
                                                        (portTickType)portMAX_DELAY);
            }

            if(strstr(event->data,"{\"cmd\":\"reset\"}"))
            {
                printf("Restarting now.\n");
                fflush(stdout);
                esp_restart();
            }
            
            if(strstr(event->data,"{\"cmd\":\"ota\"}"))
            {
                printf("req ota now.\n");
                set_ota_fig(LONON_OTA_FIG,START_OTA);
                ESP_LOGI(TAG,"启动固件升级");
                ESP_LOGI(TAG,"重启后进行固件升级");
                vTaskDelay(1000 / portTICK_PERIOD_MS);
                esp_restart();
            }
            
            break;
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
    return ESP_OK;
}

static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    mqtt_event_handler_cb(event_data);
}

/*

    函数功能：启动mqtt服务器
    函数名称：lonon_mqtt_app_start

*/
void lonon_mqtt_app_start(void)
{
    for(int i = 0;i < 5;i ++)
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    
    esp_mqtt_client_config_t mqtt_cfg = {
        
    };
    
    printf("mqtt login info!\n\n");
    /*
        port
    */
    mqtt_cfg.port = TENCENT_MQTT_PORT;
    printf("mqtt_cfg.port = %u\n",mqtt_cfg.port);

    /*
        url         
    */
    static char mqtt_info_url[64];
    memset(mqtt_info_url,'\0',sizeof(mqtt_info_url));
    sprintf(mqtt_info_url,TENCENT_MQTT_URL_PART,TENCENT_MQTT_PRODUCT_ID);
    mqtt_cfg.uri = mqtt_info_url;

    printf("mqtt_cfg.uri = %s\n",mqtt_cfg.uri);
     /*
        client_id
    */   
    static char mqtt_info_client_id[32];
    memset(mqtt_info_client_id,'\0',sizeof(mqtt_info_client_id));
    sprintf(mqtt_info_client_id,"%s%s",TENCENT_MQTT_PRODUCT_ID,TENCENT_MQTT_DEVICE_NAME);
    mqtt_cfg.client_id = mqtt_info_client_id;

    printf("mqtt_cfg.client_id = %s\n",mqtt_cfg.client_id);
    /*
        username   
    */
    static char mqtt_info_client_username[64];
    memset(mqtt_info_client_username,'\0',sizeof(mqtt_info_client_username));
    sprintf(mqtt_info_client_username,"%s%s%s",TENCENT_MQTT_PRODUCT_ID,TENCENT_MQTT_DEVICE_NAME,TENCENT_MQTT_USERNAME_PART);
    mqtt_cfg.username = mqtt_info_client_username;

    printf("mqtt_cfg.username = %s\n",mqtt_cfg.username);
    /*
        生成腾讯云mqtt服务器登录密码
    */
    static char mqtt_info_password[128];
    unsigned char hex_password[HMAC_SHA256_DIGEST_SIZE];

    memset(hex_password,0x00,sizeof(hex_password));
    hmac_sha256_build(hex_password,(const unsigned char *)mqtt_cfg.username,strlen(mqtt_cfg.username),(const unsigned char *)TENCENT_MQTT_KEY,strlen(TENCENT_MQTT_KEY));
    memset(mqtt_info_password,'\0',sizeof(mqtt_info_password));

    for(int i = 0;i < HMAC_SHA256_DIGEST_SIZE;i ++)
        sprintf(mqtt_info_password + strlen(mqtt_info_password),"%02x",hex_password[i]);

    sprintf(mqtt_info_password + strlen(mqtt_info_password),"%s",TENCENT_MQTT_PASSWORD_PART);
    mqtt_cfg.password = mqtt_info_password;    

    printf("mqtt_cfg.password = %s\n\n",mqtt_cfg.password);    

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
    esp_mqtt_client_start(client);
}



/*
    函数功能：获取设备名称
    备注：即mac地址
*/
char *get_esp32_mac_address()
{
    static char mac_sringp[32];

    uint8_t mac_addr[6];
    memset(mac_addr,0,sizeof(mac_addr));
    esp_efuse_mac_get_default(mac_addr);

    sprintf(mac_sringp,"%02x%02x%02x%02x%02x%02x",mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);

    return mac_sringp;
}








